<?php

declare(strict_types=1);
/**
 * 
 */
namespace WanZ\App\User\Middleware;

use Hyperf\Utils\Context;
use WanZ\App\Utils\Prometheus\PrometheusFactory;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Server\MiddlewareInterface;

class RequestStatisticsMiddleware implements MiddlewareInterface
{
    /**
     * @param ServerRequestInterface      $request
     * @param RequestHandlerInterface     $handler
     * @return ResponseInterface
     */    
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $requestStartTime = microtime(true);

        $response = $handler->handle($request);

        $reqPath = $request->getUri();

        if ($reqPath == '/common/get-metrics' || $reqPath == '/user/status' || $reqPath == '/') {
            return $response;
        }

        try {
            //记录接口响应时间值（秒）
            $durationTime = round(microtime(true) - $requestStartTime, 5);

            //记录指标
            $labels = [$reqPath, $request->getMethod(), $response->getStatusCode()];

            //初始化prometheus
            PrometheusFactory::statisticsRequest()->initHistogram(
                $this->getNamespace(),
                $this->getName(),
                $this->getHelp(),
                $this->getDefaultLabels(),
                $this->defaultBuckets()
            )->observe($durationTime, $labels);
        } catch (\Throwable $e) {}

        return $response;
    }

    /**
     * 获取指标的命名空间名称
     * @return string
     */
    private function getNamespace(): string
    {
        return 'user_center_api';
    }

    /**
     * 获取名字
     * @return string
     */
    private function getName(): string
    {
        return 'request_duration';
    }

    /**
     * 获取labels值
     * @return string[]
     */
    private function getDefaultLabels(): array
    {
        return ['route', 'method', 'statusCode'];
    }

    /**
     * 获取帮助说明
     * @return string
     */
    private function getHelp(): string
    {
        return 'API请求的持续时间';
    }

    /**
     * 获取持续时间的区间段（秒）
     * @return array
     */
    private function defaultBuckets(): array
    {
        return [
            0.01,
            0.025,
            0.075,
            0.1,
            0.25,
            0.5,
            0.75,
            1.0,
            1.5,
            2.0,
            2.5,
            3.0,
            3.5,
            4.0,
            4.5,
            5.0,
            5.5,
            6.0,
            6.5,
            7.0,
            7.5,
            8.0,
            8.5,
            9.0,
            9.5,
            10.0,
            10.5,
            11.0,
            11.5,
            12.0,
            12.5,
            13.0,
            13.5,
            14.0,
            14.5,
            15.0,
            15.5,
            16.0,
            17.0,
        ];
    }

}
